home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-01 / snip0493.zip / BIGFAC.C < prev    next >
C/C++ Source or Header  |  1993-04-05  |  3KB  |  123 lines

  1. /*
  2. **  bigfac.c -- put into the public domain by Carl Declerck
  3. */
  4.  
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <string.h>
  8.  
  9. #define BUFFLEN 8192
  10. #define BUFFER ((char *) malloc(BUFFLEN))
  11.  
  12. void main (void);
  13. void multiply (char *, char *, char *);
  14. void zero_buffer (char *);
  15. void minus_one (char *);
  16. int  isnull (char *);
  17. void factorial (char *);
  18.  
  19. void main (void)
  20. {
  21.       char *g = BUFFER;
  22.  
  23.       printf ("Enter a number: ");
  24.       scanf ("%s", g);
  25.       printf ("Factorial of %s is: ", g);
  26.       factorial (g);
  27.       printf ("%s\n", g);
  28.       free (g);
  29. }
  30.  
  31. void multiply (char *g1, char *g2, char *g3)
  32. {
  33.       int gp1, gp2, cumpos, respos, mod, div;
  34.       int cmod, cdiv, resoff, wdig1, wdig2, base;
  35.  
  36.       zero_buffer (g3);
  37.       for (gp2 = strlen(g2) - 1; gp2 >= 0; gp2--)
  38.       {
  39.             wdig2 = *(g2 + gp2) - 48;
  40.             resoff = strlen(g2) - gp2 - 1;
  41.             respos = BUFFLEN - resoff - 2;
  42.             for (gp1 = strlen(g1) - 1; gp1 >= 0; gp1--)
  43.             {
  44.                   wdig1 = *(g1 + gp1) - 48;
  45.                   mod = (wdig1 * wdig2) % 10;
  46.                   div = (wdig1 * wdig2) / 10;
  47.                   base = *(g3 + respos) - 48;
  48.                   cmod = (base + mod) % 10;
  49.                   cdiv = (base + mod) / 10 + div;
  50.                   *(g3 + respos) = (char)(cmod + 48);
  51.                   cumpos = --respos;
  52.                   while (cdiv > 0)
  53.                   {
  54.                         base = *(g3 + cumpos) - 48;
  55.                         *(g3 + cumpos--) = (char)((base + cdiv) % 10 + 48);
  56.                         cdiv = (base + cdiv) / 10;
  57.                   }
  58.             }
  59.       }
  60.       for (respos = 0; *(g3 + respos) == '0'; respos++)
  61.             ;
  62.       strcpy (g3, (char *) (g3 + respos));
  63.       if (*g3 == 0)
  64.             strcpy (g3, "0");
  65. }
  66.  
  67. void zero_buffer (char *buff)
  68. {
  69.       int cnt;
  70.  
  71.       for (cnt= 0; cnt < BUFFLEN; cnt++)
  72.             *(buff + cnt) = '0';
  73.       *(buff + BUFFLEN - 1) = 0;
  74. }
  75.  
  76. void minus_one (char *g)
  77. {
  78.       int p;
  79.       char digit;
  80.  
  81.       p = strlen(g) - 1;
  82.       digit = *(g + p);
  83.       while (digit == '0')
  84.       {
  85.             *(g + p--) = '9';
  86.             digit = *(g + p);
  87.       }
  88.       *(g + p) -= 1;
  89. }
  90.  
  91. int isnull (char *g)
  92. {
  93.       int p, ok = 1;
  94.  
  95.       for (p = 0; p < (int)(strlen(g)); p++)
  96.             if (*(g + p) != '0')
  97.                   ok = 0;
  98.       return (ok);
  99. }
  100.  
  101. void factorial (char *g)
  102. {
  103.       char *h1 = BUFFER, *h2 = BUFFER;
  104.  
  105.       strcpy (h1, "1");
  106.       while (!isnull(g))
  107.       {
  108.             multiply (h1, g, h2);
  109.             strcpy (h1, h2);
  110.             minus_one (g);
  111.       }
  112.       strcpy (g, h1);
  113.       free (h1);
  114.       free (h2);
  115. }
  116.  
  117. /*
  118. **  The principal function is multiply(), it 'multiplies' two
  119. **  character-strings of arbritrary length and puts the result
  120. **  into a third.  8192 bytes is enough for 1000!, beyond that
  121. **  the buffer-size may need to be incremented.
  122. */
  123.